package com.huangsm.book.designmodel.key;

import javax.validation.constraints.Max;
import java.util.concurrent.Semaphore;

/**
 * 信号量的使用
 *
 * @author huang
 * @date 2019/2/20
 */
public class Pool {
    private static final int MAX_AVAILABLE = 100;
    /**
     * 最大可以有100个许可，并且采用公平规则
     */
    private final Semaphore semaphore = new Semaphore(MAX_AVAILABLE, true);

    public Object getItem() throws InterruptedException {
        //申请一个许可
        semaphore.acquire();
        return getNextAvailableItem();
    }

    public void putItem(Object x) {
        //将给定项放回池内

        if (markAsUnused(x)) {
            //标记未被使用
            //新增一个可用项，释放一个下㐓
            //请求资源的线程被激活一个
            semaphore.release();
        }
    }

    /**
     * 存放对象池中的复用对象
     */
    protected Object[]items=null;
    /**
     * 用于标示池中的项是否正在被使用
     */
    protected boolean[] used=new boolean[MAX_AVAILABLE];

    protected synchronized Object getNextAvailableItem() {
        for (int i = 0; i < MAX_AVAILABLE; i++) {
            //如果当前项未被使用，则获得他
            if (!used[i]){
                //将当前项标记为已经使用
                used[i]=true;
                return items[i];
            }
        }
        return null;
    }

    protected synchronized boolean markAsUnused(Object item) {
        for (int i = 0; i < MAX_AVAILABLE; i++) {
        //找到给定项的索引
            if (item==items[i]){
                if (used[i]){
                    used[i]=false;
                    return true;
                }else{
                    return false;
                }
            }
        }
        return false;
    }

}
